<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- Copyright (C) 1988-2023 Free Software Foundation, Inc.

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with the
Invariant Sections being "Funding Free Software", the Front-Cover
Texts being (a) (see below), and with the Back-Cover Texts being (b)
(see below).  A copy of the license is included in the section entitled
"GNU Free Documentation License".

(a) The FSF's Front-Cover Text is:

A GNU Manual

(b) The FSF's Back-Cover Text is:

You have freedom to copy and modify this GNU Manual, like GNU
     software.  Copies published by the Free Software Foundation raise
     funds for GNU development. -->
<!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Changing Multiple RTL SSA Instructions (GNU Compiler Collection (GCC) Internals)</title>

<meta name="description" content="Changing Multiple RTL SSA Instructions (GNU Compiler Collection (GCC) Internals)">
<meta name="keywords" content="Changing Multiple RTL SSA Instructions (GNU Compiler Collection (GCC) Internals)">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<link href="index.html#Top" rel="start" title="Top">
<link href="Option-Index.html#Option-Index" rel="index" title="Option Index">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="Changing-RTL-Instructions.html#Changing-RTL-Instructions" rel="up" title="Changing RTL Instructions">
<link href="Sharing.html#Sharing" rel="next" title="Sharing">
<link href="Changing-One-RTL-SSA-Instruction.html#Changing-One-RTL-SSA-Instruction" rel="prev" title="Changing One RTL SSA Instruction">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
blockquote.indentedblock {margin-right: 0em}
blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
blockquote.smallquotation {font-size: smaller}
div.display {margin-left: 3.2em}
div.example {margin-left: 3.2em}
div.lisp {margin-left: 3.2em}
div.smalldisplay {margin-left: 3.2em}
div.smallexample {margin-left: 3.2em}
div.smalllisp {margin-left: 3.2em}
kbd {font-style: oblique}
pre.display {font-family: inherit}
pre.format {font-family: inherit}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: inherit; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: inherit; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.nolinebreak {white-space: nowrap}
span.roman {font-family: initial; font-weight: normal}
span.sansserif {font-family: sans-serif; font-weight: normal}
ul.no-bullet {list-style: none}
-->
</style>


</head>

<body lang="en">
<a name="Changing-Multiple-RTL-SSA-Instructions"></a>
<div class="header">
<p>
Previous: <a href="Changing-One-RTL-SSA-Instruction.html#Changing-One-RTL-SSA-Instruction" accesskey="p" rel="prev">Changing One RTL SSA Instruction</a>, Up: <a href="Changing-RTL-Instructions.html#Changing-RTL-Instructions" accesskey="u" rel="up">Changing RTL Instructions</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
</div>
<hr>
<a name="Changing-Multiple-RTL-SSA-Instructions-1"></a>
<h4 class="subsubsection">14.21.8.2 Changing Multiple RTL SSA Instructions</h4>

<p>The process for changing multiple instructions is similar
to the process for changing single instructions
(see <a href="Changing-One-RTL-SSA-Instruction.html#Changing-One-RTL-SSA-Instruction">Changing One RTL SSA Instruction</a>).  The pass should
again start the change attempt with:
</p>
<div class="smallexample">
<pre class="smallexample">auto attempt = crtl-&gt;ssa-&gt;new_change_attempt ();
</pre></div>

<p>and keep <code>attempt</code> in scope for the duration of the change
attempt.  It should then construct an <code>rtl_ssa::insn_change</code>
for each change that it wants to make.
</p>
<p>After this, it should combine the changes into a sequence of
<code>rtl_ssa::insn_change</code> pointers.  This sequence must be in
reverse postorder; the instructions will remain strictly in the
order that the sequence specifies.
</p>
<p>For example, if a pass is changing exactly two instructions,
it might do:
</p>
<div class="smallexample">
<pre class="smallexample">rtl_ssa::insn_change *changes[] = { &amp;change1, change2 };
</pre></div>

<p>where <code>change1</code>&rsquo;s instruction must come before <code>change2</code>&rsquo;s.
Alternatively, if the pass is changing a variable number of
instructions, it might build up the sequence in a
<code>vec&lt;rtl_ssa::insn_change *&gt;</code>.
</p>
<p>By default, <code>rtl_ssa::restrict_movement</code> assumes that all
instructions other than the one passed to it will remain in their
current positions and will retain their current uses and definitions.
When changing multiple instructions, it is usually more effective
to ignore the other instructions that are changing.  The sequencing
described above ensures that the changing instructions remain
in the correct order with respect to each other.
The way to do this is:
</p>
<div class="smallexample">
<pre class="smallexample">if (!rtl_ssa::restrict_movement (change, insn_is_changing (changes)))
  return false;
</pre></div>

<p>Similarly, when <code>rtl_ssa::restrict_movement</code> is detecting
whether a register can be clobbered, it by default assumes that
all other instructions will remain in their current positions and
retain their current form.  It is again more effective to ignore
changing instructions (which might, for example, no longer need
to clobber the flags register).  The way to do this is:
</p>
<div class="smallexample">
<pre class="smallexample">if (!rtl_ssa::recog (change, insn_is_changing (changes)))
  return false;
</pre></div>

<p>When changing multiple instructions, the important question is usually
not whether each individual change is worthwhile, but whether the changes
as a whole are worthwhile.  The way to test this is:
</p>
<div class="smallexample">
<pre class="smallexample">if (!rtl_ssa::changes_are_worthwhile (changes))
  return false;
</pre></div>

<p>The process for changing single instructions makes sure that one
<code>rtl_ssa::insn_change</code> in isolation is valid.  But when changing
multiple instructions, it is also necessary to test whether the
sequence as a whole is valid.  For example, it might be impossible
to satisfy all of the <code>move_range</code>s at once.
</p>
<p>Therefore, once the pass has a sequence of changes that are
individually correct, it should use:
</p>
<div class="smallexample">
<pre class="smallexample">if (!crtl-&gt;ssa-&gt;verify_insn_changes (changes))
  return false;
</pre></div>

<p>to check whether the sequence as a whole is valid.  If all checks pass,
the final step is:
</p>
<div class="smallexample">
<pre class="smallexample">confirm_change_group ();
crtl-&gt;ssa-&gt;change_insns (changes);
</pre></div>

<p>Putting all this together, the process for a two-instruction change is:
</p>
<div class="smallexample">
<pre class="smallexample">auto attempt = crtl-&gt;ssa-&gt;new_change_attempt ();

rtl_ssa::insn_change change (insn1);
change1.new_defs = &hellip;;
change1.new_uses = &hellip;;
change1.move_range = &hellip;;

rtl_ssa::insn_change change (insn2);
change2.new_defs = &hellip;;
change2.new_uses = &hellip;;
change2.move_range = &hellip;;

rtl_ssa::insn_change *changes[] = { &amp;change1, change2 };

auto is_changing = insn_is_changing (changes);
if (!rtl_ssa::restrict_movement (change1, is_changing)
    || !rtl_ssa::restrict_movement (change2, is_changing))
  return false;

insn_change_watermark watermark;
// Use validate_change etc. to change INSN1's and INSN2's patterns.
&hellip;
if (!rtl_ssa::recog (change1, is_changing)
    || !rtl_ssa::recog (change2, is_changing)
    || !rtl_ssa::changes_are_worthwhile (changes)
    || !crtl-&gt;ssa-&gt;verify_insn_changes (changes))
  return false;

confirm_change_group ();
crtl-&gt;ssa-&gt;change_insns (changes);
</pre></div>

<hr>
<div class="header">
<p>
Previous: <a href="Changing-One-RTL-SSA-Instruction.html#Changing-One-RTL-SSA-Instruction" accesskey="p" rel="prev">Changing One RTL SSA Instruction</a>, Up: <a href="Changing-RTL-Instructions.html#Changing-RTL-Instructions" accesskey="u" rel="up">Changing RTL Instructions</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
</div>



</body>
</html>
